//
//  BCSkinTool.m
//  Bcircle
//
//  Created by licong on 2019/6/13.
//  Copyright © 2019 Bcircle. All rights reserved.
//

#import "BCSkinTool.h"
#import "BCThemeHeader.h"
#import <Objc/runtime.h>
#import <UIKit/UIKit.h>

NSString *const plainTextColor = @"plainTextColor";
NSString *const commentColor   = @"commentColor";
NSString *const functionColor  = @"functionColor";
NSString *const keywordColor   = @"keywordColor";
NSString *const stringColor    = @"stringColor";
NSString *const numberColor    = @"numberColor";
NSString *const variableColor  = @"variableColor";
NSString *const schemaColor    = @"schemaColor";
NSString *const tableColor     = @"tableColor";
NSString *const columnColor    = @"columnColor";
NSString *const backgroundColor = @"backgroundColor";
NSString *const selectionColor  = @"selectionColor";
NSString *const fontName        = @"fontName";
NSString *const fontSize        = @"fontSize";
NSString *const lineNumberFontColor = @"lineNumberFontColor";
NSString *const lineNumberBackgroundColor = @"lineNumberBackgroundColor";

#pragma mark - BCSkinTool
@interface BCSkinTool ()
@property(nonatomic,strong)NSHashTable *hashTable;
@property(nonatomic,strong)NSDictionary *colorSet;
@end

@implementation BCSkinTool

static BCSkinTool *sHelper = nil;
+ (instancetype)shareInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sHelper = [[BCSkinTool alloc] init];
        sHelper.hashTable = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
        [sHelper setColorThemeType:(ThemeType_Default)];
    });
    return sHelper;
}

/// 初始化皮肤
+ (instancetype)setupAppSkin {
    return [BCSkinTool shareInstance];
}

/// 改变皮肤配置
-(void)setColorThemeType:(ThemeType)themeType{
    switch (themeType) {
        case ThemeType_Default:
            [self setupSkinConfig:@"Default.json"];
            break;
        case ThemeType_Dark:
            [self setupSkinConfig:@"Dark.json"];
            break;
        case ThemeType_Sunset:
            [self setupSkinConfig:@"Sunset.json"];
            break;
    }
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    [self changeTheme];
    CFAbsoluteTime endTime = (CFAbsoluteTimeGetCurrent() - startTime);
    NSLog(@"setColorThemeType 方法耗时: %f ms", endTime * 1000.0);
}

//#if 0
//-(void)changeThemeColor{
//    for (UIView *view in _hashTable.mutableCopy) {
//        CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
//        NSString *name = view.backgroundColor.name;
//        if (name) {
//            view.backgroundColor = BCAppearenceColor(name);
//            CFAbsoluteTime endTime = (CFAbsoluteTimeGetCurrent() - startTime);
//            NSLog(@"方法耗时0: %f ms", endTime * 1000.0);
//        }
//
//        CFAbsoluteTime startTime1 = CFAbsoluteTimeGetCurrent();
//        if([view respondsToSelector:@selector(textColor)]){
//            UIColor *color = [view performSelector:@selector(textColor)];
//            if(color.name){
//                [view performSelector:@selector(setTextColor:) withObject:BCAppearenceColor(color.name)];
//            }
//            CFAbsoluteTime endTime1 = (CFAbsoluteTimeGetCurrent() - startTime1);
//            NSLog(@"方法耗时1: %f ms", endTime1 * 1000.0);
//        }
//    }
//}


-(void)changeThemeColor {
    
    for (UIView *view in _hashTable.mutableCopy) {
        
        unsigned int count;
        Ivar *ivars = class_copyIvarList([view class], &count);    
        
        for (unsigned int i = 0; i < count; i++) {
            
            Ivar ivar = ivars[i];
            const char *s = ivar_getTypeEncoding(ivar);
            NSLog(@"view type = %@ ivar name = %s type = %s",NSStringFromClass([view class]),ivar_getName(ivar),s);
            // find out all UIColor properties
            if (strcmp(s, "@\"UIColor\"") == 0) {
                const char *ivarName = ivar_getName(ivar);
                UIColor *color = object_getIvar(view, ivar);
                NSLog(@"ivar name = %s type = %s name = %@",ivar_getName(ivar),s,color.name);
                if ( color && color.name ) {
                    [view setValue:BCAppearenceColor(color.name) forKey:[NSString stringWithUTF8String:ivarName]];
                }
            }
        }
        free(ivars);
    }
}

-(void)changeTheme {
    for (UIView * view in _hashTable.mutableCopy) {
        Class c = [view class];
                
        do {
            NSLog(@"class = %@",NSStringFromClass(c));
            NSLog(@"%d",[c isSubclassOfClass:[NSObject class]]);
            NSLog(@"%d",[c isKindOfClass:[NSObject class]]);
            [self changeThemeForView:view class:c];
            c = class_getSuperclass(c);
        } while ( ![c isEqual:[NSObject class]] );
    }
}

-(void)changeThemeForView:(UIView *)view class:(Class)cls{
    
    unsigned int count;
    
    objc_property_t *properties = class_copyPropertyList(cls, &count);
    
    for ( int i = 0; i < count; i++ ) {
        
        NSString *name = [NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding];
        
        if ( ![name hasPrefix:@"_"] && [name hasSuffix:@"Color"]) {
            
            SEL getter = [self returnGetterWithPropertyName:name];
            NSLog(@"property name = %@",name);
            
            if ([view respondsToSelector:getter]) {
                
                SEL setter = [self returnSetterWithPropertyName:name];
                id color = [view performSelector:getter];
                
                if (CGRectEqualToRect(((UIView *)view).frame, CGRectMake(100, 100, 100, 30))) {
                    NSLog(@"[color isKindOfClass:[UIColor class]] = %d",[color isKindOfClass:[UIColor class]]);
                    NSLog(@"[label respondsToSelector:setter] = %d",[view respondsToSelector:setter]);
                }
                
                if (color && [color isKindOfClass:[UIColor class]] && [view respondsToSelector:setter]) {
                    if (((UIColor *)color).name) {
                        NSLog(@"color.name = %@",((UIColor *)color).name);
                        [view performSelector:setter withObject:BCAppearenceColor(((UIColor *)color).name)];
                    }
                }
            }
        }
    }
}

-(SEL)returnGetterWithPropertyName:(NSString *)propertyName {
    return NSSelectorFromString(propertyName);
}

-(SEL)returnSetterWithPropertyName:(NSString *)propertyName {
    propertyName = [propertyName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[propertyName substringToIndex:1] capitalizedString]];
    propertyName = [NSString stringWithFormat:@"set%@:",propertyName];
    return NSSelectorFromString(propertyName);
}

///
- (void)addThemeObserveView:(UIView *)view {
    if (view && ![_hashTable containsObject:view]) {
        [self.hashTable addObject:view];
    }
}

- (void)removeThemeObserveView:(UIView *)view {
    if (view && [_hashTable containsObject:view]) {
        [self.hashTable removeObject:view];
    }
}

-(UIColor *)getColorWithName:(NSString *)name{
    if (_colorSet) {
        return [UIColor colorWithThemeName:name hexString:[_colorSet objectForKey:name]];
    }else{
        return [UIColor yellowColor];
    }
}

-(UIImage *)getImageWithName:(NSString *)imageName{
    return [UIImage imageWithThemeName:imageName];
}

///
- (void)setupSkinConfig:(NSString *)configName{
    NSString *path = [[NSBundle mainBundle] pathForResource:configName?:@"Default.json" ofType:nil];
    NSError *err;
    NSString *str = [NSString stringWithContentsOfFile:path encoding:(NSUTF8StringEncoding) error:nil];
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    _colorSet = [NSJSONSerialization JSONObjectWithData:data options:0 error:&err];    
}



@end
